package dao

import (
	"context"
	"go-shop-api/internal/model"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

type UserDao struct {
	*gorm.DB
}

// NewUserDao 把init init_mysql的Db复制过来
func NewUserDao(ctx context.Context) *UserDao {
	return &UserDao{NewDBClient(ctx)}
}

// NewUserDaoByDB  方法二 把init中的db拿过来  ，当一个函数里，有多个dao ,既有userDao，又有GoodsDao ,可用这个方法实现对db的复用,都使用一个db，减少对数据库的链接
func NewUserDaoByDB(db *gorm.DB) *UserDao {
	return &UserDao{db}
}

// ExistOrNotByAccount 通过 账号/用户名/手机号/邮箱 判断用户是否存在
func (d *UserDao) ExistOrNotByAccount(account string) (user *model.User, exist bool, err error) {
	var count int64
	err = d.DB.Model(&model.User{}).Where("account=?", account).
		Or("nickname=?", account).
		Or("email=?", account).
		Or("Phone=?", account).
		Count(&count).Error
	if count == 0 {
		return user, false, err
	}
	err = d.DB.Model(&model.User{}).
		Where("account=?", account).
		Or("nickname=?", account).
		Or("email=?", account).
		Or("Phone=?", account).
		First(&user).Error
	//如果user == 空
	//if user == nil || err == gorm.ErrRecordNotFound {
	//	return nil, false, err
	//}
	if err != nil {
		return user, false, err
	}
	return user, true, nil
}

// UserCreate 创建用户
func (d *UserDao) UserCreate(uc *model.User) error {
	return d.DB.Model(&model.User{}).Create(uc).Error
	//return d.DB.Model(&model.User{}).Create(&uc).Error  //一样可以添加
	//为何把参数 uc 更换成 uc *model.UserCreate就不行了？报错 go reflect: Field index out of range
	//zydh:因为会和前面的model(&model.User{})去字段映射，所以会报错reflect 映射错误
}

/*
		CheckPassword 检验密码
		encryptPwd string  已经加密的字符
	    password string 还未加密的字符
*/
func CheckPassword(encryptPwd, password string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(encryptPwd), []byte(password))
	return err == nil
	//如果err == nil 返回 true，反之
}

// GetUserByUid 通过id获取用户信息
func (d *UserDao) GetUserByUid(id uint) (user *model.User, err error) {
	err = d.DB.Model(&model.User{}).Where("id=?", id).First(&user).Error
	return
}

// UpdateUserById 通过用户id修改用户信息
func (d *UserDao) UpdateUserById(uid uint, user *model.User) (err error) {
	return d.DB.Model(&model.User{}).Where("id=?", uid).Updates(&user).Error
}

//// AfterGetUserByUid 钩子  当查询数据后操作
//func (u *model.User) AfterGetUserByUid(tx *gorm.DB) (err error) {
//	if !u.IsValid() {
//		return errors.New("rollback invalid user")
//	}
//	return nil
//}
